package com.example.okhttp;

import okhttp3.*;
import org.springframework.lang.Nullable;

import java.io.IOException;
import java.net.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Main {

    public static void main(String[] args) {
//        manyGet();
        String host = null;
        try {
            host = new URL("test").getHost();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        System.out.println(host);
    }

    private static void manyGet(){
        ExecutorService pool = Executors.newCachedThreadPool();
        int i=0;
        while (i++<10){
            pool.execute(()->{
                get();
            });
        }
        System.out.println();
        pool.shutdown();
    }


    private static void get() {
        OkHttpClient httpClient = new OkHttpClient().newBuilder()
                .eventListenerFactory(new ListenerFactory())
//                .callTimeout(2, TimeUnit.SECONDS)
                .connectTimeout(2,TimeUnit.SECONDS)
//                .readTimeout(2,TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder().get().url("http://127.0.0.1:8081/okhttp/test").build();

        try {
            Response response = httpClient.newCall(request).execute();
//
            System.out.println(response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }

//        RealCall.newRealCall();

    }

    private static class ListenerFactory implements EventListener.Factory{

        EventListener T_LISTENER = new EventListener() {

            long i;
            ThreadLocal<String> tl = new ThreadLocal<>();

            private void print(Call call, String method){
//                StringBuffer stringBuffer = map.getOrDefault(uid.get(),new StringBuffer());
//                stringBuffer.append("method:").append(method).append("  ").append(System.currentTimeMillis() - i).append("ms");
//                System.out.println(uid.get()+" Url:"+call.request().url()+" "+method+": useTime="+(System.currentTimeMillis()-i)+"ms");
//                System.out.println(method);
                tl.set(tl.get()+","+method+":"+(System.currentTimeMillis()-i)+"ms");
//                System.out.println(stringBuffer);
            }

            @Override
            public void callStart(Call call) {
                i = System.currentTimeMillis();
                print(call,"callStart");
            }

            @Override
            public void dnsStart(Call call, String domainName) {
                print(call,"dnsStart");
            }

            @Override
            public void dnsEnd(Call call, String domainName, List<InetAddress> inetAddressList) {
                print(call,"dnsEnd");
            }

            @Override
            public void connectStart(Call call, InetSocketAddress inetSocketAddress, Proxy proxy) {
                print(call,"connectStart");
            }

            @Override
            public void secureConnectStart(Call call) {
                print(call,"secureConnectStart");
            }

            @Override
            public void secureConnectEnd(Call call, @Nullable Handshake handshake) {
                print(call,"secureConnectEnd");
            }

            @Override
            public void connectEnd(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, @Nullable Protocol protocol) {
                print(call,"connectEnd");
            }

            @Override
            public void connectFailed(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, @Nullable Protocol protocol, IOException ioe) {
                print(call,"connectFailed");
            }

            @Override
            public void connectionAcquired(Call call, Connection connection) {
                print(call,"connectionAcquired");
            }

            @Override
            public void connectionReleased(Call call, Connection connection) {
                print(call,"connectionReleased");
            }

            @Override
            public void requestHeadersStart(Call call) {
                print(call,"requestHeadersStart");
            }

            @Override
            public void requestHeadersEnd(Call call, Request request) {
                print(call,"requestHeadersEnd");
            }

            @Override
            public void requestBodyStart(Call call) {
                print(call,"requestBodyStart");
            }

            @Override
            public void requestBodyEnd(Call call, long byteCount) {
                print(call,"requestBodyEnd");
            }

            @Override
            public void requestFailed(Call call, IOException ioe) {
                print(call,"requestFailed");
            }

            @Override
            public void responseHeadersStart(Call call) {
                print(call,"responseHeadersStart");
            }

            @Override
            public void responseHeadersEnd(Call call, Response response) {
                print(call,"responseHeadersEnd");
            }

            @Override
            public void responseBodyStart(Call call) {
                print(call,"responseBodyStart");
            }

            @Override
            public void responseBodyEnd(Call call, long byteCount) {
                print(call,"responseBodyEnd");
            }

            @Override
            public void responseFailed(Call call, IOException ioe) {
                print(call,"responseFailed");
            }

            @Override
            public void callEnd(Call call) {
                print(call,"callEnd");
                System.out.println(tl.get());
                tl.remove();
            }

            @Override
            public void callFailed(Call call, IOException ioe) {
                print(call,"callFailed");
                tl.remove();
            }
        };

        public ThreadLocal<String> uid = new ThreadLocal<>();
        @Override
        public EventListener create(Call call) {
            UUID uuid = UUID.randomUUID();
            uid.set(uuid.toString());
            return T_LISTENER;
        }

    }


}
